#pragma once

#include <memory>
#include <vector>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>
#include <atomic>
#include "TaskQueue.h"
#include <Logger.h>
namespace GiSo {

class ThreadPool {
public:
    using Task = std::function<void()>;

    // 构造函数，绑定外部提供的 TaskQueue 数组
    ThreadPool(size_t num_threads)
        : m_Running(true){
        m_Queues.resize(num_threads);
        for (size_t i = 0; i < num_threads; ++i) {
            m_Queues[i] = std::make_shared<TaskQueue>();
            m_Workers.emplace_back(&ThreadPool::WorkerThread, this, i);
        }
    }

    // 析构函数，停止线程池
    ~ThreadPool() {
        Stop();
        for (auto& worker : m_Workers) {
            if (worker.joinable()) {
                worker.join();
            }
        }
    }

    TaskQueue::Ptr GetQueue(size_t idx) {
        return m_Queues[idx];
    }

    void Stop() {
        m_Running = false;
        for (size_t i = 0; i < m_Workers.size(); ++i) {
            m_Queues[i]->GetConditionVariable().notify_all(); // 唤醒所有线程
        }
    }

private:
    void WorkerThread(size_t thread_idx) {
        auto myQueue = m_Queues[thread_idx];
        std::mutex& myMutex = myQueue->GetMutex();
        std::condition_variable& myCv = myQueue->GetConditionVariable();

        while (m_Running) {
            std::optional<Task> task;
            {
                task = myQueue->PopFront();
                if (!task) {
                    std::unique_lock<std::mutex> lock(myMutex);
                    myCv.wait(lock);
                }
            }
            if (task) {
                (*task)();
            }
        }
    }

    std::vector<TaskQueue::Ptr> m_Queues; // 引用外部队列
    std::vector<std::thread> m_Workers;
    std::atomic<bool> m_Running;
};

} // namespace GiSo